#include "muduo/proto/codec.h"

#include "muduo/proto/dispatcher.h"
#include "muduo/base/Logging.h"
#include "muduo/base/Mutex.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/TcpServer.h"
#include "muduo/net/TcpClient.h"
#include "muduo/net/EventLoopThread.h"
#include "muduo/base/CountDownLatch.h"

#include "request.pb.h"
#include <iostream>
#include <functional>
using namespace std;

class Client
{
public:

typedef std::shared_ptr<google::protobuf::Message> MessagePtr;  
    typedef std::shared_ptr<ljh::AddResponse> AddResponsePtr;  
    typedef std::shared_ptr<ljh::TranslateResponse> TranslateResponsePtr; // 确保类型名正确

Client(const std::string &sip, int sport)  
        : _latch(1),  
          _client(_loopthread.startLoop(), muduo::net::InetAddress(sip, sport), "Client"),  
      _dispatcher(std::bind(&Client::onUnkownMessage, this,  
            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),  
          _codec(std::bind(&ProtobufDispatcher::onProtobufMessage, &_dispatcher,  //qing
            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) {  
  
        _dispatcher.registerMessageCallback<ljh::TranslateResponse>(  
            std::bind(&Client::onTranslate, this,  
            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));  
        _dispatcher.registerMessageCallback<ljh::AddResponse>(  
            std::bind(&Client::onAdd, this,  
            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));  
  
        _client.setMessageCallback(std::bind(&ProtobufCodec::onMessage, &_codec,  
             std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));  
        _client.setConnectionCallback(std::bind(&Client::onConnection, this, std::placeholders::_1));  
  
}

void connect()
{
 _client.connect();
 _latch.wait();//堵塞等待，直到链接成功
}
void Translate(const std::string &msg)
{
ljh::TranslateRequest req;
req.set_msg(msg);
send(&req);


}

 void Add(int num1,int num2)//y
 {
   ljh::AddRequest req;
    req.set_num1(num1);
    req.set_num2(num2);
    send(&req);
 }
bool send(const google::protobuf::Message * message)
{
   if(_conn->connected())//连接正常再发送
   {
     _codec.send(_conn,*message);
       return true;
   }
   else{
      return false;
   }
}

void  onTranslate(const muduo::net::TcpConnectionPtr& conn,const TranslateResponsePtr& message,muduo::Timestamp){
std::cout<<"翻译结果："<<message->msg()<<std::endl;
}
void onAdd(const muduo::net::TcpConnectionPtr&conn,const AddResponsePtr& message,muduo::Timestamp){
std::cout<<"加法结果"<<message->result()<<std::endl;
}
void onUnkownMessage(const muduo::net::TcpConnectionPtr& conn,const MessagePtr& message,muduo::Timestamp)
 {
    LOG_INFO<<"onUnkownMessage:"<<message->GetTypeName();
    conn->shutdown();
 }
 void onConnection(const muduo::net::TcpConnectionPtr& conn)
 {
   if(conn->connected())
   {
      _latch.countDown();//唤醒主线程中的堵塞
      _conn=conn;
   }else
   {
      //关闭连接
      _conn.reset();
   }
 }


private:
     muduo::CountDownLatch _latch;//实现同步
     muduo::net::EventLoopThread _loopthread;//异步循环处理线程
     muduo::net::TcpClient _client;//客户端
     muduo::net::TcpConnectionPtr _conn;//客户端对应的连接
     ProtobufDispatcher _dispatcher;//请求分发器
     ProtobufCodec     _codec;//协议处理器



};

int main()
{

   Client client("127.0.0.1",8085);
   client.connect();
   client.Translate("hello");
   client.Add(88,66);
   sleep(1);
   return 0;
}